#include "CmdMgr.h"

#include <core/FileSys.h>
#include <core/Utility.h>
#include <core/core.h>
#include <uam/UserAccountManager.h>

#include <QDir>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>

CmdMgr::CmdMgr() {}

void CmdMgr::loadQBMenu() {
  QJsonDocument doc =
      CoreUtility::openJsonDoc(FileSys::instance()->appCfgDir() + "/menu.json");
  if (doc.isNull()) {
    logError(MODULE_NAME, "Open qb menu config file failed!");
    return;
  } else {
    QJsonArray jMenu = doc.array();
    for (auto jMenuCatogory : jMenu) {
      QJsonObject menuCatogory = jMenuCatogory.toObject();
      if (!menuCatogory.contains("submenu")) continue;

      QJsonArray jMenuPanelList = menuCatogory["submenu"].toArray();
      for (auto jMenuPanel : jMenuPanelList) {
        QJsonObject menuPanel = jMenuPanel.toObject();
        if (!menuPanel.contains("submenu")) continue;

        QJsonArray jMenuItemList = menuPanel["submenu"].toArray();
        for (QJsonValue jMenuItem : jMenuItemList) {
          QJsonObject menuItem = jMenuItem.toObject();

          int id = menuItem["id"].toInt();
          QString name = menuItem["title"].toString();
          int baseId = 0;

          if (!m_cmds.contains(id) && !m_cmds.contains(baseId)) continue;

          Command& cmdQBMenu = m_cmds[id];
          if (cmdQBMenu.module().isEmpty()) continue;

          cmdQBMenu.setName(name);

          if (menuItem.contains("permission")) {
            QString permission = menuItem["permission"].toString();
            if (!permission.isEmpty()) {
              const char* sValue =
                  SSUserAccountManager::instance().GetPermission().GetValue(
                      permission.toStdString().c_str());
              if (strcmp(sValue, "1") != 0) cmdQBMenu.setAuthed(false);
            }
          }
          if (menuItem.contains("auth")) {
            QString auth = menuItem["auth"].toString();
            std::string cid = menuItem["cid"].toString().toStdString();
            if (!auth.isEmpty() && !cid.empty()) {
              CBusinessShowInfo si;
              SSUserAccountManager::instance().GetAllowBusinessAuth(
                  si, auth.toStdString().c_str());
              if (si.m_AllowList.size()) {
                bool authed = false;
                for (auto it = si.m_AllowList.begin();
                     it != si.m_AllowList.end(); it++) {
                  if (it->m_BrokerID == cid) {
                    {
                      authed = true;
                      break;
                    }
                  }
                }
                cmdQBMenu.setAuthed(authed);
              }
            }
          }

          if (menuItem.contains("abbr"))
            cmdQBMenu.setAbbr(menuItem["abbr"].toString());

          if (menuItem.contains("tag")) {
            QString tag = menuItem["tag"].toString();
            if (tag == "hot")
              cmdQBMenu.setTag(Command::CmdTag::kHot);
            else if (tag == "new") {
              cmdQBMenu.setRedPoint(
                  m_noRedpages.find(id) == m_noRedpages.end() ? true : false);
              cmdQBMenu.setTag(Command::CmdTag::kNew);
            }
          }

          if (menuItem.contains("woption")) {
            cmdQBMenu.setParamters(menuItem["woption"].toString());
          }

          if (menuItem.contains("hide") && menuItem["hide"].toBool()) {
            cmdQBMenu.setHide(true);
          }
        }
      }
    }
  }
}

void CmdMgr::loadQBWoptions() {
  QJsonDocument doc = CoreUtility::openJsonDoc(
      FileSys::instance()->appCfgDir() + "/woptions.json");
  if (doc.isNull()) {
    logError(MODULE_NAME, "Open qb woption config file failed!");
    return;
  } else {
    m_options.clear();
    QJsonArray jWoption = doc.array();
    for (auto jWoptionCatogory : jWoption) {
      QJsonObject woptionCatogory = jWoptionCatogory.toObject();
      for (QJsonObject::ConstIterator iter = woptionCatogory.constBegin();
           iter != woptionCatogory.constEnd(); ++iter) {
        m_options.insert(iter.key(), iter.value().toString());
      }

      for (auto& jCmd : m_cmds) {
        if (woptionCatogory.contains(jCmd.paramters().toUtf8().constData())) {
          jCmd.setParamters(
              woptionCatogory[jCmd.paramters().toUtf8().constData()]
                  .toString());
          break;
        }
      }
    }
  }
}

void CmdMgr::loadClickPageConfig(bool isSave /*= false*/) {
  QString configPath = FileSys::instance()->userCfgDir() + "/pageconfig.json";

  {
    QDir tempDir;
    if (!tempDir.exists(FileSys::instance()->userCfgDir())) {
      tempDir.mkpath(FileSys::instance()->userCfgDir());
    }
  }
  QJsonDocument doc = CoreUtility::openJsonDoc(configPath);
  QJsonObject* jcfgObj;
  if (!doc.isNull()) {
    jcfgObj = new QJsonObject(doc.object());
  } else {
    if (!isSave) return;
    jcfgObj = new QJsonObject();
  }
  QString sKey = "noredpages";
  if (!isSave) {
    m_noRedpages.clear();
    QJsonArray jpagesArray = jcfgObj->value(sKey).toArray();
    for (auto it : jpagesArray) {
      m_noRedpages.insert(it.toInt());
    }
  } else {
    QJsonArray jpagesArray;
    for (auto it : m_noRedpages) {
      jpagesArray.append(QJsonValue(it));
    }
    jcfgObj->insert(sKey, jpagesArray);
    QJsonDocument jdoc;
    jdoc.setObject(*jcfgObj);
    QFile cfgFile(configPath);
    if (cfgFile.open(QIODevice::WriteOnly)) {
      cfgFile.write(jdoc.toJson(QJsonDocument::Indented));
    }
    cfgFile.close();
  }
}

void CmdMgr::LoadCmdConfig() {
  QJsonDocument doc =
      CoreUtility::openJsonDoc(FileSys::instance()->appCfgDir() + "/cmds.cfg");
  if (doc.isNull()) {
    logError(MODULE_NAME, "Open command config file failed!");
    return;
  } else {
    QJsonArray cmds = doc.array();
    for (auto cmdV : cmds) {
      QJsonObject cmdObj = cmdV.toObject();
      int id = cmdObj["id"].toInt();
      QString name = cmdObj["name"].toString();
      int baseId = id;
      if (cmdObj.contains("baseCmd")) baseId = cmdObj["baseCmd"].toInt();

      Command cmd(id, name, baseId);
      if (cmdObj.contains("module")) cmd.setModule(cmdObj["module"].toString());

      m_cmds[id] = cmd;
    }
  }
}

CmdMgr& CmdMgr::instance() {
  static CmdMgr mgr;
  return mgr;
}

bool CmdMgr::execCmd(int id) {
  auto cmd = command(id);
  if (cmd) return cmd->exec();
  return false;
}

bool CmdMgr::execCmd(int id, const QString& paras) {
  auto cmd = command(id);
  if (cmd) return cmd->exec(paras);
  return false;
}

bool CmdMgr::execCmd(const QString* name, const QJsonObject* params) {
  auto cmd = m_cmds.begin();
  for (; cmd != m_cmds.end(); ++cmd) {
    if ((*name) == cmd.value().e_name()) break;
  };

  if (cmd != m_cmds.end()) return cmd->exec();  // how to use params?
  return false;
}

Command* CmdMgr::command(int id) {
  auto cmd = m_cmds.find(id);
  if (cmd != m_cmds.end()) return &cmd.value();

  return nullptr;
}

void CmdMgr::removePageRedPoint(int id) {
  auto cmd = command(id);
  if (cmd && cmd->isRedPoint()) {
    cmd->setRedPoint(false);
    m_noRedpages.insert(id);
  }
}

void CmdMgr::addCommonPage(int id) {
  if (std::find(m_commonPages.begin(), m_commonPages.end(), id) ==
      m_commonPages.end()) {
    m_commonPages.push_back(id);
    auto cmd = command(id);
    int ntype = 1;
    if (cmd) {
      cmd->commonPage(id, ntype);
    }
  }
}

void CmdMgr::setCommonPages(int* ids, int size) {
  m_commonPages.clear();
  if (ids && size > 0) {
    for (int i = 0; i < size; ++i) {
      m_commonPages.push_back(*(ids + i));
    }
  }
}

bool CmdMgr::isCommonPage(int id) {
  return std::find(m_commonPages.begin(), m_commonPages.end(), id) !=
         m_commonPages.end();
}

void CmdMgr::removeCommonPage(int id) {
  if (std::find(m_commonPages.begin(), m_commonPages.end(), id) !=
      m_commonPages.end()) {
    m_commonPages.remove(m_commonPages.indexOf(id));
    auto cmd = command(id);
    int ntype = -1;
    if (cmd) {
      cmd->commonPage(id, ntype);
    }
  }
}

void CmdMgr::setIasMenu(const QString& iasmenu) {
  m_iasmenu = iasmenu;

  QJsonDocument doc = QJsonDocument::fromJson(iasmenu.toUtf8());
  if (doc.isNull()) {
    logError(MODULE_NAME, "Open qb menu config file failed!");
    return;
  } else {
    QJsonArray jMenuItemList = doc.array();
    for (QJsonValue jMenuItem : jMenuItemList) {
      QJsonObject menuItem = jMenuItem.toObject();

      int id = menuItem["id"].toInt();
      QString name = menuItem["title"].toString();
      int baseId = 0;
      Command cmdQBMenu(id, name, baseId);

      if (menuItem.contains("abbr"))
        cmdQBMenu.setAbbr(menuItem["abbr"].toString());

      if (menuItem.contains("tag")) {
        QString tag = menuItem["tag"].toString();
        if (tag == "hot")
          cmdQBMenu.setTag(Command::CmdTag::kHot);
        else if (tag == "new") {
          cmdQBMenu.setRedPoint(
              m_noRedpages.find(id) == m_noRedpages.end() ? true : false);
          cmdQBMenu.setTag(Command::CmdTag::kNew);
        }
      }
      m_cmds[id] = cmdQBMenu;
    }
  }
}

const QString CmdMgr::LoadURL(const char* sKey) {
  auto iter = m_options.find(sKey);
  if (iter != m_options.end()) {
    return iter.value();
  }

  return "";
}

bool CmdMgr::initialize() {
  // 不要改变顺序
  loadClickPageConfig(false);
  LoadCmdConfig();
  loadQBMenu();
  loadQBWoptions();
  return true;
}

void CmdMgr::unInitialize() { loadClickPageConfig(true); }

int CmdMgr::cmdWindowId() {
  static int s_id = -1;
  return ++s_id;
}
